#include <Arduino.h>
#include <WiFi.h>
#include "atom.h"
#include <stdio.h>
#include <pthread.h>
#include <termios.h>
#include <stdlib.h>
#include "syslog.h"

#define ATOM_NONE_STANDARDIO
#include "iosdrv.h"
#include "drv_wifi_console.h"
#include "numberical.h"
#include "drv_common.h"
#include <ESPmDNS.h>
#include "wlan.h"


#define RX_BUF_SIZE (1024)
#define CONSOLE_RX_STACK     (4096)
#define CONSOLE_RX_PRI       (14)

typedef struct{
    WiFiServer *server;
    WiFiClient *client;
    SIO_PARAM param;
    uint8_t rx_buf[RX_BUF_SIZE];
    uint8_t rx_stack[CONSOLE_RX_STACK];
    ATOM_TCB tcb;
}Esp32WifiConsoleConfig;

WiFiServer _server;
WiFiClient _client;

static Esp32WifiConsoleConfig _config = {
    &_server, &_client, { 115200, 8, ssb1Bit,  spNone, FALSE, FALSE, enSioBlockingSend}, {0}, {0}, DEFAULT_TCB("net_rx")
};

static void thread_for_console(void* param)
{
    char key;
    Esp32WifiConsole *console = (Esp32WifiConsole *)param;
    Esp32WifiConsoleConfig * config = (Esp32WifiConsoleConfig*)console->Protected.config;

    for(;;){
        if(config->server->hasClient()) {
            if (config->client->connected()) {
                config->client->flush();
                config->client->stop();
            }
            *config->client = config->server->available();
        }

        if( config->client->connected()){
            while( config->client->available()){
                char data = config->client->read();
                int level = get_cc(); 
                ringPut(&console->Protected.ops.rxRing, &data, 1);
                set_cc(level); 
            }
        }else{
             atomTimerDelay(5);
        }
    }
}

static int wifi_ioctl(SioBase* sio, int function, void* arg)
{
    return NG;
}

void wifi_blocking_send(SioBase* sio, const char* buffer, size_t size)
{
    Esp32WifiConsole *console = (Esp32WifiConsole *)sio;
    Esp32WifiConsoleConfig * config = (Esp32WifiConsoleConfig*)console->Protected.config;
    
    if(config->client && config->client->connected()){
        config->client->write((uint8_t*)buffer, size);
    }   
}

static Esp32WifiConsole _console;

#define SSID_MAX_LEN (32)
static char _ssid_buf[SSID_MAX_LEN];

void Esp32WifiConsoleInit(int port)
{
    Wlan *wlan = (Wlan*)ios_open("wlan0", 0, 0 );
    if (!wlan) {
        SYSLOG(LOG_ERR, "Failed to open WLAN device");
        return;
    }
    // 启动智能配网
    if (WlanSmartConfig(wlan, "console", 5) != OK) {
        SYSLOG(LOG_ERR, "WiFi smart config failed");
        return;
    }

    // 启动 TCP 服务器
    _config.server->begin(port);

    // 其余初始化代码保持不变
    pthread_t thread;
    _console.Protected.ops.Ioctl = wifi_ioctl;
    _console.Protected.ops.BufferedSend = NULL;
    _console.Protected.ops.BlockingSend = wifi_blocking_send; 
    _console.Protected.config = &_config;
    _console.Protected.port = port;
    
    SioCreate(&_console.super, "console", &_config.param, &_console.Protected.ops, (char*)_config.rx_buf, RX_BUF_SIZE, NULL, 0 );
    atomThreadCreate(&_config.tcb, CONSOLE_RX_PRI, thread_for_console, (void*)&_console, _config.rx_stack, CONSOLE_RX_STACK, 0);
}

